package api

import (
	"ChatingYourself/global"
	"ChatingYourself/pojo"
	"ChatingYourself/util"
	"encoding/json"
	"fmt"
	"github.com/gin-gonic/gin"
	"net/http"
)

// Register 注册
func Register(c *gin.Context) {
	JsonMessage := pojo.UserInfo{}
	err := c.BindJSON(&JsonMessage)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{
			"code":    400,
			"message": "数据格式错误，请确认无误后再输入",
		})
		return
	}
	//账号检查
	if len(JsonMessage.Account) == 0 {
		c.JSON(http.StatusUnprocessableEntity, gin.H{
			"code":    422,
			"message": "账号不能为空",
		})
		return
	}
	//Email检查
	if len(JsonMessage.Email) == 0 {
		c.JSON(http.StatusUnprocessableEntity, gin.H{
			"code":    422,
			"message": "Email不能为空",
		})
		return
	}
	//Name检查
	if len(JsonMessage.Name) == 0 {
		c.JSON(http.StatusUnprocessableEntity, gin.H{
			"code":    422,
			"message": "用户名不能为空",
		})
		return
	}
	//密码
	if len(JsonMessage.Password) < 6 {
		c.JSON(http.StatusUnprocessableEntity, gin.H{
			"code":    422,
			"message": "密码不能少于6位",
		})
		return
	}
	//数据库中注册用户信息
	newUser := pojo.UserInfo{
		Account:  JsonMessage.Account,
		Name:     JsonMessage.Name,
		Email:    JsonMessage.Email,
		Password: util.MD5Encryption(JsonMessage.Password),
	}
	err = global.DBLink.Table("user_infos").Create(&newUser).Error
	if err != nil {
		fmt.Println()
		fmt.Println(err)
		fmt.Println()
		//注册失败
		c.JSON(http.StatusInternalServerError, gin.H{
			"code":    500,
			"message": "注册失败！",
		})
	} else {
		//注册成功
		c.JSON(http.StatusOK, gin.H{
			"code":    200,
			"message": "注册成功！",
		})
	}
}

// Login 登录接口
func Login(c *gin.Context) {
	JsonMessage := pojo.UserInfo{}
	err := c.BindJSON(&JsonMessage)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{
			"code":    400,
			"message": "数据格式错误，请确认无误后再输入",
		})
		return
	}
	//账号检查
	if len(JsonMessage.Account) == 0 {
		c.JSON(http.StatusUnprocessableEntity, gin.H{
			"code":    422,
			"message": "账号不能为空",
		})
		return
	}
	//密码
	if len(JsonMessage.Password) < 6 {
		c.JSON(http.StatusUnprocessableEntity, gin.H{
			"code":    422,
			"message": "密码不能少于6位",
		})
		return
	}
	compTemp := pojo.UserInfo{}
	err = global.DBLink.Table("user_infos").Where("account = ?", JsonMessage.Account).First(&compTemp).Error
	if err != nil {
		print(err)
		c.JSON(http.StatusInternalServerError, gin.H{
			"code":    500,
			"message": "查询失败！",
		})
		return
	} else {
		if util.MD5Encryption(JsonMessage.Password) != compTemp.Password {
			fmt.Println(JsonMessage.Password)
			c.JSON(http.StatusUnprocessableEntity, gin.H{
				"code":    422,
				"message": "密码错误，请检查密码是否正确！",
			})
			return
		}
		//添加在线状态
		global.OnlineUser[JsonMessage.Account] = true
		c.JSON(http.StatusOK, gin.H{
			"code":    200,
			"message": "登陆成功！",
		})
		return
	}
}

// FindPassword1 找回密码第一次POST的接口
func FindPassword1(c *gin.Context) {
	JsonMessage := pojo.ForgetPasswordMessage{}
	err := c.BindJSON(&JsonMessage)
	if err != nil {
		c.JSON(http.StatusUnprocessableEntity, gin.H{
			"code":    422,
			"message": "错误的请求",
		})
		return
	}
	if util.GetName(JsonMessage.UserID) == "" {
		c.JSON(http.StatusUnprocessableEntity, gin.H{
			"code":    422,
			"message": "不存在该用户",
		})
		return
	}
	if util.GetEmail(JsonMessage.UserID) != JsonMessage.Email {
		c.JSON(http.StatusUnprocessableEntity, gin.H{
			"code":    422,
			"message": "用户邮箱不对应",
		})
		return
	}
	global.VerificationCode[JsonMessage.UserID] = util.RandStr(5)
	util.SendEmail(util.GetEmail(JsonMessage.UserID), global.VerificationCode[JsonMessage.UserID])
	c.JSON(http.StatusOK, gin.H{
		"code":    200,
		"message": "验证码已发送",
	})
	return
}

// FindPassword2 找回密码第二次POST的接口
func FindPassword2(c *gin.Context) {
	JsonMessage := pojo.ForgetPasswordMessage{}
	err := c.BindJSON(&JsonMessage)
	if err != nil {
		c.JSON(http.StatusUnprocessableEntity, gin.H{
			"code":    422,
			"message": "错误的请求",
		})
		return
	}
	if util.GetName(JsonMessage.UserID) == "" {
		c.JSON(http.StatusUnprocessableEntity, gin.H{
			"code":    422,
			"message": "不存在该用户",
		})
		return
	}
	if util.GetEmail(JsonMessage.UserID) != JsonMessage.Email {
		c.JSON(http.StatusUnprocessableEntity, gin.H{
			"code":    422,
			"message": "用户邮箱不对应",
		})
		return
	}
	if global.VerificationCode[JsonMessage.UserID] != JsonMessage.VerificationCode {
		c.JSON(http.StatusUnprocessableEntity, gin.H{
			"code":    422,
			"message": "验证码错误",
		})
		return
	}
	util.CheckPassword(JsonMessage.UserID, JsonMessage.NewPassword)
	c.JSON(http.StatusOK, gin.H{
		"code":    200,
		"message": "密码已修改",
	})
}

// Test 测试接口
func Test(c *gin.Context) {
	type testMessage struct {
		Message string `json:"message"`
	}
	JsonMessage := testMessage{}
	err := c.BindJSON(&JsonMessage)
	if err != nil {
		c.JSON(http.StatusUnprocessableEntity, gin.H{
			"code":    422,
			"message": "错误的请求",
		})
		return
	}
	if JsonMessage.Message == "ping" {
		c.JSON(http.StatusOK, gin.H{
			"code":    200,
			"message": "pong",
		})
		return
	}
	c.JSON(http.StatusOK, gin.H{
		"code":    200,
		"message": "请求成功",
	})
	return
}

// WebsocketPing websocket实现
// 重点，用于实现服务器与客户端的长期通信，以及方便服务器主动向客户端发送消息
func WebsocketPing(c *gin.Context) {
	// 本来这边还要编写请求头，但是为了方便就没有再设置Token以及各种验证方式
	ws, err := global.UpGrader.Upgrade(c.Writer, c.Request, nil)
	if err != nil {
		return
	}
	defer ws.Close()
	// 第一次发送信息！需要从客户端获取对应ID
	_, firstMessage, err := ws.ReadMessage()
	if err != nil {
		fmt.Println(err)
		return
	}
	firstMessageRead := pojo.ShakeHandMessage{}
	err = json.Unmarshal(firstMessage, &firstMessageRead)
	if err != nil {
		fmt.Println(err)
		return
	}
	//记录用户ID对应的ws连接
	global.UserSocket[firstMessageRead.UserId] = ws
	global.OnlineUser[firstMessageRead.UserId] = true
	fmt.Printf("用户%s已经成功登录\n", firstMessageRead.UserId)
	messageRes := pojo.TransResponse{
		Status:  "1",
		Code:    200,
		Message: "成功发送",
	}
	res, _ := json.Marshal(messageRes)
	err = ws.WriteMessage(1, res)
	friends := util.GetFriends(firstMessageRead.UserId)
	if err != nil {
		return
	}
	messageFriend := pojo.LoginMessage{
		PersonalName: util.GetName(firstMessageRead.UserId),
		UserID:       firstMessageRead.UserId,
		Friends:      friends,
	}
	res, _ = json.Marshal(messageFriend)
	err = ws.WriteMessage(1, res)
	if err != nil {
		delete(global.UserSocket, firstMessageRead.UserId)
		global.OnlineUser[firstMessageRead.UserId] = false
		return
	}

	onlineUserName := make(map[string]string)
	for key, _ := range global.OnlineUser {
		onlineUserName[key] = util.GetName(key)
	}
	messageAllUser := pojo.LoginMessage{
		PersonalName: "system",
		UserID:       firstMessageRead.UserId,
		Friends:      onlineUserName,
	}
	res, _ = json.Marshal(messageAllUser)
	err = global.UserSocket[firstMessageRead.UserId].WriteMessage(1, res)
	if err != nil {
		delete(global.UserSocket, firstMessageRead.UserId)
		global.OnlineUser[firstMessageRead.UserId] = false
		return
	}
	//向好友广播上线信息
	loginMessage := pojo.TransMessage{
		FromAccount: "SystemAlert",
		ToAccount:   "",
		Message:     "您的好友" + firstMessageRead.UserId + "已上线",
	}
	for key, _ := range friends {
		if global.OnlineUser[key] {
			loginMessage.ToAccount = key
			res, _ = json.Marshal(loginMessage)
			err = global.UserSocket[key].WriteMessage(1, res)
			if err != nil {
				continue
			}
		}
	}
	//开始通信
	for {
		mt, message, err := ws.ReadMessage()
		if err != nil {
			fmt.Println(err)
			delete(global.UserSocket, firstMessageRead.UserId)
			global.OnlineUser[firstMessageRead.UserId] = false
			break
		}
		messageGet := pojo.TransMessage{}
		err = json.Unmarshal(message, &messageGet)
		fmt.Println(messageGet)
		if err != nil {
			fmt.Println(err)
			delete(global.UserSocket, firstMessageRead.UserId)
			global.OnlineUser[firstMessageRead.UserId] = false
			return
		}
		messageRes = pojo.TransResponse{
			Status:  "1",
			Code:    200,
			Message: "成功发送",
		}
		// 如果是聊天室的信息
		if messageGet.ToAccount == "systemchat" {
			sender := messageGet.FromAccount
			messageGet.Message = messageGet.FromAccount + ":" + messageGet.Message
			messageGet.FromAccount = "systemchat"
			cnt := 0
			for key, toAccount := range global.UserSocket {
				if key == sender {
					continue
				}
				messageGet.ToAccount = key
				messageSend, _ := json.Marshal(messageGet)
				err = toAccount.WriteMessage(1, messageSend)
				if err != nil {
					messageRes.Status = "-1"
					messageRes.Message = "发送失败"
					cnt++
				}
			}
			//没有一个发送成功
			if cnt == len(global.UserSocket) && len(global.UserSocket) != 0 {
				messageRes.Status = "-1"
				messageRes.Message = "发送失败"
				res, _ := json.Marshal(messageRes)
				err = ws.WriteMessage(1, res)
				if err != nil {
					break
				}
				continue
			}
			messageRes.Message = "systemchat发送成功"
			res, _ := json.Marshal(messageRes)
			err = ws.WriteMessage(1, res)
			if err != nil {
				break
			}
			continue
		}
		if !global.OnlineUser[messageGet.ToAccount] {
			messageRes.Status = "-1"
			messageRes.Message = "发送失败，对方不在线"
		} else {
			messageSend, _ := json.Marshal(messageGet)
			err = global.UserSocket[messageGet.ToAccount].WriteMessage(1, messageSend)
			if err != nil {
				messageRes.Status = "-1"
				messageRes.Message = "发送失败"
			}
		}
		res, _ := json.Marshal(messageRes)
		err = ws.WriteMessage(mt, res)
	}
	delete(global.UserSocket, firstMessageRead.UserId)
	global.OnlineUser[firstMessageRead.UserId] = false
	onlineUserName = make(map[string]string)
	for key, _ := range global.UserSocket {
		onlineUserName[key] = util.GetName(key)
	}
	messageAllUser = pojo.LoginMessage{
		PersonalName: "system",
		UserID:       firstMessageRead.UserId,
		Friends:      onlineUserName,
	}
	res, _ = json.Marshal(messageAllUser)
	for key, _ := range global.UserSocket {
		err = global.UserSocket[key].WriteMessage(1, res)
		if err != nil {
			continue
		}
	}
}

// AddFriend 添加好友接口
func AddFriend(c *gin.Context) {
	JsonMessage := pojo.AddFriendMessage{}
	err := c.BindJSON(&JsonMessage)
	if err != nil {
		print(err)
		return
	}
	//判断是否存在该用户
	if util.GetName(JsonMessage.GoalID) == "" {
		c.JSON(http.StatusUnprocessableEntity, gin.H{
			"code":    422,
			"message": "不存在该用户",
		})
		return
	}
	//该用户是否在线
	if !global.OnlineUser[JsonMessage.GoalID] {
		c.JSON(http.StatusUnprocessableEntity, gin.H{
			"code":    422,
			"message": "对方用户不在线",
		})
		return
	}
	SystemMessage := pojo.TransMessage{
		FromAccount: "SystemFriend",
		ToAccount:   JsonMessage.GoalID,
		Message:     JsonMessage.UserID,
	}
	messageSend, _ := json.Marshal(SystemMessage)
	err = global.UserSocket[JsonMessage.GoalID].WriteMessage(1, messageSend)
	if err != nil {
		print(err)
		return
	}
	_, message, err := global.UserSocket[JsonMessage.GoalID].ReadMessage()
	if err != nil {
		print(err)
		return
	}
	messageRes := pojo.TransMessage{}
	err = json.Unmarshal(message, &messageRes)
	if err != nil {
		print(err)
		return
	}
	//同意
	if messageRes.Message == "YES" {
		messageRes = pojo.TransMessage{
			FromAccount: "SystemFriend",
			ToAccount:   JsonMessage.UserID,
			Message:     "成功添加" + JsonMessage.GoalID + "为好友",
		}
		messageResSend, _ := json.Marshal(messageRes)
		err = global.UserSocket[JsonMessage.UserID].WriteMessage(1, messageResSend)
		if err != nil {
			print(err)
			return
		}
		util.AddFriends(JsonMessage.GoalID, JsonMessage.UserID)
		c.JSON(http.StatusOK, gin.H{
			"code":    200,
			"message": "成功添加" + JsonMessage.GoalID + "为好友",
		})
		return
	} else { /*不同意*/
		messageRes = pojo.TransMessage{
			FromAccount: "SystemFriend",
			ToAccount:   JsonMessage.UserID,
			Message:     JsonMessage.GoalID + "拒绝了您的好友申请",
		}
		messageResSend, _ := json.Marshal(messageRes)
		err = global.UserSocket[JsonMessage.UserID].WriteMessage(1, messageResSend)
		if err != nil {
			print(err)
			return
		}
	}
}

// ShakeWindow 窗口抖动信息
func ShakeWindow(c *gin.Context) {
	JsonMessage := pojo.ShakeMessage{}
	err := c.BindJSON(&JsonMessage)
	if err != nil {
		print(err)
		return
	}
	if !global.OnlineUser[JsonMessage.ToAccount] {
		c.JSON(http.StatusInternalServerError, gin.H{
			"code":    500,
			"message": "对方不在线",
		})
		return
	}
	messageSend, _ := json.Marshal(JsonMessage)
	err = global.UserSocket[JsonMessage.ToAccount].WriteMessage(1, messageSend)
	if err != nil {
		c.JSON(http.StatusUnprocessableEntity, gin.H{
			"code":    422,
			"message": "发送失败",
		})
		return
	}
	c.JSON(http.StatusOK, gin.H{
		"code":    200,
		"message": "发送成功",
	})
}
